﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace CodePlex.Silverlight.Controls
{
    [TemplatePart(Name = "RootElement", Type = typeof(FrameworkElement))] 
    [TemplatePart(Name = "HeaderElement", Type = typeof(ContentControl))] 
    [TemplatePart(Name = "NavItemBorderElement", Type = typeof(Border))] 
    [TemplatePart(Name = "Normal State", Type = typeof(Storyboard))]
    [TemplatePart(Name = "MouseOver State", Type = typeof(Storyboard))]
    [TemplatePart(Name = "Selected State", Type = typeof(Storyboard))]
    [TemplatePart(Name = "Disabled State", Type = typeof(Storyboard))]
    public class NavigationItem : System.Windows.Controls.ContentControl
    {
        Storyboard currentState;
        public static readonly DependencyProperty HeaderProperty;
        public static readonly DependencyProperty IsSelectedProperty;

        static NavigationItem()
        {
            IsSelectedProperty =  DependencyProperty.Register("IsSelected", typeof(bool),
                                       typeof(NavigationItem), new PropertyChangedCallback(NavigationItem.OnIsSelectedChanged));
            HeaderProperty =      DependencyProperty.Register("Header", typeof(object),
                                         typeof(NavigationItem), null);

        }

        public NavigationItem()
        {
            base.MouseLeftButtonDown += new MouseButtonEventHandler(this.OnMouseLeftButtonDown);
            base.MouseEnter += new MouseEventHandler(this.OnMouseEnter);
            base.MouseLeave += new MouseEventHandler(this.OnMouseLeave);
        }

        internal bool DefaultItem { get; set; }
        public FrameworkElement ElementRoot { get; set; }
        public ContentControl ElementHeader { get; set; }
        public Border ElementNavItemBorder { get; set; }        
        public object Header
        {
            get { return (object)GetValue(HeaderProperty); }
            set { SetValue(HeaderProperty, value); }
        }
        public bool IsMouseOver { get; set; }  
        public bool IsSelected
        {
            get { return (bool)GetValue(IsSelectedProperty); }
            set { SetValue(IsSelectedProperty, value); }
        }
        public NavigationPane NavigationPaneParent { get; set; }
        public Storyboard StateMouseOver { get; set; }
        public Storyboard StateNormal { get; set; }
        public Storyboard StateSelected { get; set; }
        public Storyboard StateDisabled { get; set; }

        internal void ChangeVisualState(Storyboard state)
        {
            Storyboard storyboard = this.currentState;
            if ((state != storyboard) && (state != null))
            {
                if (storyboard != null)
                {
                    storyboard.Stop();
                }
                this.currentState = state;
                state.Begin();
            }
        }

        protected override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            this.ElementRoot = base.GetTemplateChild("RootElement") as FrameworkElement;
            this.ElementHeader = base.GetTemplateChild("HeaderElement") as ContentControl;
            this.ElementNavItemBorder = base.GetTemplateChild("NavItemBorderElement") as Border;            
            if (this.ElementRoot != null)
            {
                this.StateNormal = this.ElementRoot.Resources["Normal State"] as Storyboard;
                this.StateMouseOver = this.ElementRoot.Resources["MouseOver State"] as Storyboard;
                this.StateSelected = this.ElementRoot.Resources["Selected State"] as Storyboard;
                this.StateDisabled = this.ElementRoot.Resources["Disabled State"] as Storyboard;
                if (this.DefaultItem)
                {             
                    ChangeVisualState(StateSelected);
                }
            }
            this.NavigationPaneParent = Helpers.FindParentOfType<NavigationPane>(this);            
        }
  
        public void OnMouseEnter(object sender, MouseEventArgs e)
        {
            e.Handled = true;
            this.IsMouseOver = true;
            if (base.IsEnabled)
            {
                this.UpdateVisualState();
            }
        }

        public void OnMouseLeave(object sender, MouseEventArgs e)
        {
            e.Handled = true;
            this.IsMouseOver = false;
            if (base.IsEnabled)
            {
                this.UpdateVisualState();
            }
        }

        internal void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;          
            if (base.IsEnabled)
            {
                this.NavigationPaneParent.SelectedItem = this;
            }
            this.IsSelected = true;
            UpdateVisualState();
            base.Focus();
        }
        
        private static void OnIsSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            NavigationItem navItem = d as NavigationItem;
            (navItem.Content as UIElement).Visibility = (navItem.IsSelected) ? Visibility.Visible : Visibility.Collapsed;
            navItem.UpdateVisualState();
        }

        internal void UpdateVisualState()
        {
            if (this.IsSelected)
            {
                this.ChangeVisualState(this.StateSelected ?? this.StateNormal);
            } else if (this.IsMouseOver)
            {
                this.ChangeVisualState(this.StateMouseOver ?? this.StateNormal);
            }
            else
            {
                this.ChangeVisualState(this.StateNormal);
            }
        }
    }
}
